# middleware.py

from datetime import timedelta
from django.utils import timezone
from management.models import UserControl
from .tasks import UserDataTasks
from functools import wraps
from rest_framework_simplejwt.authentication import JWTAuthentication

from .updater import DataUpdater
import logging
logger = logging.getLogger('management')


# 装饰器，为 request 对象添加跳过中间件的标志
def skip_middleware_user_activity(view_func):

    @wraps(view_func)
    def wrapped_view(*args, **kwargs):
        # 设置标志，供中间件识别是否跳过处理
        setattr(args[0], '_skip_user_activity_middleware', True)
        return view_func(*args, **kwargs)
    return wrapped_view


# 记录用户上次活跃时间 并 管理用户任务函数的中间件
class UserActivityMiddleware:

    EXCLUDED_PATHS = [
        '/admin',
        '/static',
        '/media',
        '/health',
        '/status',
        '/swagger',
        '/swagger.json',
        '/swagger.yaml',
        '/api/token/refresh/',
        '/api/token/blacklist/',
        '/api/user/register/',
        '/api/user/login/',
        '/api/user/logout/',
        '/api/user/verify_email/'
    ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 跳过特定路径
        if any(request.path.startswith(path) for path in self.EXCLUDED_PATHS):
            return self.get_response(request)
        # 检查是否有跳过标志，若有则跳过中间件逻辑
        if getattr(request, '_skip_user_activity_middleware', False):
            return self.get_response(request)

        # 手动加载用户认证信息
        jwt_authenticator = JWTAuthentication()
        try:
            user_auth_tuple = jwt_authenticator.authenticate(request)
            if user_auth_tuple:
                request.user, _ = user_auth_tuple
        except Exception as e:
            logger.exception(f"Error authenticating JWT: {e}")
            print(f"Error authenticating JWT: {e}")

        # print("未跳过中间件逻辑")
        # 如果用户已认证并且未设置跳过标志，执行活动触发逻辑
        try:
            user_id = request.user.id
            if user_id:
                # print("真触发了")
                self.trigger_user_activity(user_id)
        except AttributeError:
            logger.exception("UserActivityMiddleware: request.user.id is not accessible.")
            print("UserActivityMiddleware: request.user.id is not accessible.")

        response = self.get_response(request)
        return response


    @staticmethod
    def trigger_user_activity(user_id):
        try:
            # 使用 user_id 获取或创建用户控制对象
            user_control, created = UserControl.objects.get_or_create(user_id=user_id)

            # 检查用户上次活动时间是否存在
            if not user_control.last_activity:
                user_control.last_activity = timezone.now()
                user_control.task_count += 1  # default是0

                # 调用初始化任务函数
                UserDataTasks.submit_or_replace_task(user_id, UserDataTasks.async_initialize_user_data)

                # 插入递归任务函数，6小时后执行
                UserDataTasks.submit_or_replace_task(user_id, UserDataTasks.async_process_user_data_cycle,
                                                     countdown=21600)
                user_control.next_task_time = timezone.now() + timedelta(hours=6)

                user_control.save()
                logger.info("Initialized OK!")
            # 若用户最近活跃时间已超过10分钟
            elif timezone.now() - user_control.last_activity > timedelta(minutes=10):
                # 更新最后活动时间为当前时间
                user_control.last_activity = timezone.now()

                # 若超过3天未活跃
                if timezone.now() - user_control.last_activity > timedelta(days=3):
                    logger.info("Too long no active")
                    if user_control.task_count == 0:
                        user_control.task_count += 1
                        UserDataTasks.submit_or_replace_task(user_id, UserDataTasks.async_process_user_data_cycle,
                                                             countdown=21600)
                        user_control.next_task_time = timezone.now() + timedelta(hours=6)
                        user_control.save()
                        DataUpdater.update_data_fetch_user_id(user_id)

                # 若未超过3天但任务计数异常地为0
                elif user_control.task_count == 0:
                    logger.info("task_count exception")
                    user_control.task_count = 1
                    user_control.next_task_time = timezone.now() + timedelta(hours=6)
                    UserDataTasks.submit_or_replace_task(user_id, UserDataTasks.async_process_user_data_cycle,
                                                         countdown=21600)
                user_control.save()
            # save内移，不是每次都要save

        except Exception as e:
            logger.exception(f"Error in UserActivityMiddleware: {e}")
            print(f"Error in UserActivityMiddleware: {e}")
